package com.xcc.core.netty.ssl;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManagerFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClientSslContextFactory {
    
    private static final Logger log=LoggerFactory.getLogger(MyClientSslContextFactory.class) ;

    private static final String PROTOCOL = "TLS";

    private static SSLContext sslContext;

    public static SSLContext getClientContext(String caPath, String storepass){
        if(sslContext !=null) return sslContext;
        InputStream trustInput = null;

        try{
            //信任库
            TrustManagerFactory tf = null;
            if (caPath != null) {
                //密钥库KeyStore
                KeyStore ks = KeyStore.getInstance("JKS");
                //加载客户端证书
                trustInput = new FileInputStream(caPath);
                ks.load(trustInput, storepass.toCharArray());
                tf = TrustManagerFactory.getInstance("SunX509");
                // 初始化信任库
                tf.init(ks);
            }

            //双向认证时需要加载自己的证书
            /*KeyManagerFactory kmf = null;
            if (pkPath != null) {
                KeyStore ks = KeyStore.getInstance("JKS");
                keyIn = new FileInputStream(pkPath);
                ks.load(keyIn, storepass.toCharArray());
                kmf = KeyManagerFactory.getInstance("SunX509");
                kmf.init(ks, keypass.toCharArray());
            }*/

            sslContext = SSLContext.getInstance(PROTOCOL);
            //设置信任证书. 双向认证时，第一个参数kmf.getKeyManagers()
            sslContext.init(null,tf == null ? null : tf.getTrustManagers(), null);

        }catch(Exception e){
            throw new Error("Failed to init the client-side SSLContext");
        }finally{
            if(trustInput !=null){
                try {
                    trustInput.close();
                } catch (IOException e) {
                    log.info("close InputStream.", e);
                }
            }
        }

        return sslContext;
    }
    
    public static SSLEngine getsslClient() {
        String clientPath = System.getProperty("user.dir")+ "/src/main/resources/yqClient.jks";
      //客户方模式
        SSLContext sslContext =
                MyClientSslContextFactory.getClientContext(clientPath, "cstorepass654");
        //设置为服务器模式
        SSLEngine sslEngine = sslContext.createSSLEngine();
        sslEngine.setUseClientMode(true);
        //是否需要验证客户端 。 如果是双向认证，则需要将其设置为true，同时将client证书添加到server的信任列表中
        sslEngine.setNeedClientAuth(false);  
        return sslEngine;
    }
 
    
}
